<html>
<head><meta charset="utf-8"><title>rustc missing an optimisation? · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/rustc.20missing.20an.20optimisation.3F.html">rustc missing an optimisation?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="209127212"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/rustc%20missing%20an%20optimisation%3F/near/209127212" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thomas Winwood <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/rustc.20missing.20an.20optimisation.3F.html#209127212">(Sep 04 2020 at 18:37)</a>:</h4>
<p>Here are two samples of source code - a <a href="https://rust.godbolt.org/z/7er15d">Rust sample</a> compiled with Rust 1.46.0 using the <code>thumbv4m-none-eabi</code> target, and a <a href="https://godbolt.org/z/nPqGaP">C sample</a> compiled using clang 10.0.0. (The results are identical using Rust nightly and clang trunk.) They are as far as I can tell functionally identical.</p>
<div class="codehilite"><pre><span></span><code><span class="cp">#![no_std]</span><span class="w"></span>

<span class="cp">#[repr(C)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">Color</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">red</span>: <span class="kt">u8</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">green</span>: <span class="kt">u8</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">blue</span>: <span class="kt">u8</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">pub</span><span class="w"> </span><span class="k">extern</span><span class="w"> </span><span class="s">&quot;C&quot;</span><span class="w"> </span><span class="k">fn</span> <span class="nf">convert</span><span class="p">(</span><span class="n">color</span>: <span class="nc">Color</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">u16</span> <span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="p">((((</span><span class="n">color</span><span class="p">.</span><span class="n">red</span><span class="w"> </span><span class="o">&gt;&gt;</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="mh">0x1F</span><span class="p">)</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">u16</span><span class="p">)</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"></span>
<span class="w">    </span><span class="o">|</span><span class="w"> </span><span class="p">((((</span><span class="n">color</span><span class="p">.</span><span class="n">green</span><span class="w"> </span><span class="o">&gt;&gt;</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="mh">0x1F</span><span class="p">)</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">u16</span><span class="p">)</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w"></span>
<span class="w">    </span><span class="o">|</span><span class="w"> </span><span class="p">((((</span><span class="n">color</span><span class="p">.</span><span class="n">blue</span><span class="w"> </span><span class="o">&gt;&gt;</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="mh">0x1F</span><span class="p">)</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">u16</span><span class="p">)</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="mi">10</span><span class="p">)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>


<div class="codehilite"><pre><span></span><code><span class="cp">#include</span> <span class="cpf">&lt;stdint.h&gt;</span><span class="cp"></span>

<span class="k">struct</span> <span class="n">Color</span> <span class="p">{</span>
    <span class="kt">uint8_t</span> <span class="n">red</span><span class="p">;</span>
    <span class="kt">uint8_t</span> <span class="n">green</span><span class="p">;</span>
    <span class="kt">uint8_t</span> <span class="n">blue</span><span class="p">;</span>
<span class="p">};</span>

<span class="kt">uint16_t</span> <span class="nf">convert</span><span class="p">(</span><span class="k">struct</span> <span class="n">Color</span> <span class="n">color</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">(((</span><span class="n">color</span><span class="p">.</span><span class="n">red</span> <span class="o">&gt;&gt;</span> <span class="mi">3</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x1F</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="mi">0</span><span class="p">)</span>
        <span class="o">|</span> <span class="p">(((</span><span class="n">color</span><span class="p">.</span><span class="n">green</span> <span class="o">&gt;&gt;</span> <span class="mi">3</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x1F</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="mi">5</span><span class="p">)</span>
        <span class="o">|</span> <span class="p">(((</span><span class="n">color</span><span class="p">.</span><span class="n">blue</span> <span class="o">&gt;&gt;</span> <span class="mi">3</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x1F</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="mi">10</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>


<p>However, Rust appears to be missing an optimisation - clang calculates <code>0x1F &lt;&lt; 10</code> and delays adding together the intermediate values until the very end, whereas Rust starts with <code>0x1F &lt;&lt; 5</code> and therefore has to perform an extra <code>mov</code>. How can rustc be improved here?</p>



<a name="209127445"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/rustc%20missing%20an%20optimisation%3F/near/209127445" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/rustc.20missing.20an.20optimisation.3F.html#209127445">(Sep 04 2020 at 18:39)</a>:</h4>
<p>I'd open an issue so this doesn't get lost on zulip</p>



<a name="209127564"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/rustc%20missing%20an%20optimisation%3F/near/209127564" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thomas Winwood <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/rustc.20missing.20an.20optimisation.3F.html#209127564">(Sep 04 2020 at 18:40)</a>:</h4>
<p>Sure. I wanted to make sure a wizard couldn't get more detailed information for the purposes of the issue before I posted it.</p>



<a name="209127783"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/rustc%20missing%20an%20optimisation%3F/near/209127783" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thomas Winwood <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/rustc.20missing.20an.20optimisation.3F.html#209127783">(Sep 04 2020 at 18:42)</a>:</h4>
<p>Done. <a href="https://github.com/rust-lang/rust/issues/76336">https://github.com/rust-lang/rust/issues/76336</a></p>



<a name="209127862"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/rustc%20missing%20an%20optimisation%3F/near/209127862" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/rustc.20missing.20an.20optimisation.3F.html#209127862">(Sep 04 2020 at 18:43)</a>:</h4>
<p>maybe look at the difference in LLVM IR?</p>



<a name="209127893"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/rustc%20missing%20an%20optimisation%3F/near/209127893" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/rustc.20missing.20an.20optimisation.3F.html#209127893">(Sep 04 2020 at 18:43)</a>:</h4>
<p>this sounds like an LLVM issue</p>



<a name="209129429"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/rustc%20missing%20an%20optimisation%3F/near/209129429" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/rustc.20missing.20an.20optimisation.3F.html#209129429">(Sep 04 2020 at 18:58)</a>:</h4>
<p>my gut feeling is some kind of overflow check is interfering</p>



<a name="209129627"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/rustc%20missing%20an%20optimisation%3F/near/209129627" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/rustc.20missing.20an.20optimisation.3F.html#209129627">(Sep 04 2020 at 19:00)</a>:</h4>
<p>there are no overflow checks in that code though</p>



<a name="209129655"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/rustc%20missing%20an%20optimisation%3F/near/209129655" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/rustc.20missing.20an.20optimisation.3F.html#209129655">(Sep 04 2020 at 19:00)</a>:</h4>
<p>unless you count the shift masking, but that's optimized out trivially</p>



<a name="209134483"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/rustc%20missing%20an%20optimisation%3F/near/209134483" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Wesley Wiser <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/rustc.20missing.20an.20optimisation.3F.html#209134483">(Sep 04 2020 at 19:51)</a>:</h4>
<p><span class="user-mention silent" data-user-id="338008">Thomas Winwood</span> <a href="#narrow/stream/122651-general/topic/rustc.20missing.20an.20optimisation.3F/near/209127212">said</a>:</p>
<blockquote>
<p>(The results are identical using Rust nightly and clang trunk.)</p>
</blockquote>
<p>Worth noting that we have upgraded our version of LLVM between Rust 1.46 and <code>nightly</code>. I believe that upgrade is now in <code>beta</code> but I could be wrong about that.</p>



<a name="209135850"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/rustc%20missing%20an%20optimisation%3F/near/209135850" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/rustc.20missing.20an.20optimisation.3F.html#209135850">(Sep 04 2020 at 20:07)</a>:</h4>
<p>yes, 1.47-beta has LLVM 11</p>



<a name="209139149"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/rustc%20missing%20an%20optimisation%3F/near/209139149" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Wesley Wiser <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/rustc.20missing.20an.20optimisation.3F.html#209139149">(Sep 04 2020 at 20:47)</a>:</h4>
<p>So if <code>1.47-beta</code> does not have that issue, then I think you can consider this "solved".</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>